package cn.flyingocean.dao;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * del()等方法使用前需先判断对象是否存在
 * @param <T>
 */
public class BaseDao<T> {
    @Autowired
    public SessionFactory sf;

    /**
     * 开启一个hibernate会话,需要手动关闭
     * @anthor xstar
     * @return Session
     */
    public Session getSession(){
        return sf.openSession();
    }

    /**
     * 依据传入的hql查询对象
     * @author xstar
     * @param hql 传入hql语句
     * @return T:查询成功 null:查询对象不存在
     */
    protected T queryOne(String hql){
        Session session = getSession();
        Query query = session.createQuery(hql);
        T r = (T) query.uniqueResult();

        session.close();
        return r;
    }

    /**
     * 持久化传入的对象(主键匹配,存在相同的主键对象将覆盖)
     * @author xstar
     * @param thing 要保存的对象
     */
    protected void save(T thing){
        Session session = getSession();
        Transaction tx = null;
        try{
            tx = session.beginTransaction();
            session.save(thing);

            tx.commit();
            session.flush();
        }catch (Exception e){
            tx.rollback();
            e.printStackTrace();
        }finally {
            session.close();
        }
    }

    /**
     * 删除传入的对象(主键匹配)
     * @author xstar
     * @param thing
     */
    protected void del(T thing){
        Session session = getSession();
        Transaction tx = null;
        try{
            tx = session.beginTransaction();
            session.delete(thing);

            tx.commit();
            session.flush();
        }catch (Exception e){
            tx.rollback();
            e.printStackTrace();
        }finally {
            session.close();
        }
    }

    /**
     * 更新传入的对象(主键匹配)
     * @author xstar
     * @param thing
     */
    protected void update(T thing){
        Session session = getSession();
        Transaction tx = null;
        try{
            tx = session.beginTransaction();
            session.update(thing);

            tx.commit();
            session.flush();
        }catch (Exception e){
            tx.rollback();
            e.printStackTrace();
        }finally {
            session.close();
        }
    }
}
